#!/usr/bin/env python
#
# http://banssh.googlecode.com/svn/trunk/python/
#
# This is a heartbeat test
#  
#  Is the port listening? netstat -nap|grep '16001'|grep 'audisp-bot'|grep 'LISTEN'  
import os,sys,re,datetime,pexpect,time
# Note time for sleep

LOG="/var/log/banssh/attacks"
# This is the HeartBeat Log
LOGHB="/var/log/banssh/attacksHB"
HBLOGIN="bansshHB"
SERVER="localhost"

# This is server
def check_listen():
    f=os.popen("netstat -nap|grep '16001'|grep 'audisp-bot'|grep 'LISTEN'","r")
    s=f.readlines()
    f.close()
    p=re.compile('LISTEN')
    for i in s:
       m=p.search(i)
       if m:
          return True
    return False


# This is banssh
# ESTABLISHED 13437/bansshcpp
def check_listen_banssh():
    f=os.popen("netstat -nap|grep '16001'|grep -e 'ESTABLISHED'|grep -e 'bansshcpp'","r")
    s=f.readlines()
    f.close()
    p=re.compile('ESTABLISHED')
    for i in s:
       m=p.search(i)
       if m:
          return True
    return False


def login(n):
    p=pexpect.spawn('ssh '+str(HBLOGIN)+'@'+str(n))
    p.expect('.ssword:*')
    time=datetime.datetime.now().strftime("%Y.%m.%d \(%A\) %H:%M:*")
    p.sendline('fakepassword')
    p.expect('.ssword:*')
    p.sendline('fakepassword')
    p.expect('.ssword:*')
    p.terminate()
    return time



def searchlog(n):
    f=open(LOGHB,'r')
    d=f.readlines()
    f.close()
    d.reverse()
    p=re.compile(str(n))
    for i in d[0:40]:
        m=p.search(i)
        if m:
          return True
    return False

def log(n):
    f=open('LoginTest','a')
    f.write(datetime.datetime.now().strftime("%Y.%m.%d (%A) %H:%M:%S")+": ")
    f.write(str(n))
    f.write('\n')
    f.close()

def logHB(n):
    f=open(LOGHB,'a')
    f.write(datetime.datetime.now().strftime("%Y.%m.%d (%A) %H:%M:%S")+": ")
    f.write(str(n))
    f.write('\n')
    f.close()


def check_bheartbeat():
    try:
       mode=os.stat("/var/log/banssh/lock/bheartbeat")
    except:
       return False
    finally:
       f=open("/var/log/banssh/lock/bheartbeat")
       t=f.readlines()
       f.close()
       p=re.compile('count=([0-9][0-9]*)')
       for i in t:
           m=p.search(i)
           if m:
              a=m.group(1)
              return int(a)
       return False



    
def looptest(sleep,loops):
    for i in range(0,loops):
         time.sleep(sleep)
         if searchlog(login(SERVER)):
             log('No worries')
         else:
             log('Hmm ... strange.')


def check_listen_wrapper():
    a=0
    while(abs(a) < 14):
         if check_listen() == False:
             a+=3
         else:
             a-=1
         time.sleep(6)
    if a > 0:
         return False
    return True


def check_listen_wrapper_banssh():
    a=0
    while(abs(a) < 14):
         if check_listen_banssh() == False:
             a+=3
         else:
             a-=1
         time.sleep(6)
    if a > 0:
         return False
    return True


def check_login_wrapper():
    a=0
    while(abs(a) < 14):
      if searchlog(login(SERVER)):
         a+=4
      else:
         a-=1  
      time.sleep(20)
    if a < 0:
      return False
    else:
      return True


def RestartBansshd():
    f=os.popen("/etc/init.d/bansshd restart","r")
    m=f.readlines()
    f.close()

def RestartAudit():
    f=os.popen("/etc/init.d/auditd restart","r")
    m=f.readlines()
    f.close()

def Restartbheartbeat():
    logHB("Restarting bheartbeat")
    f=os.popen("/etc/init.d/bheartbeat restart","r")
    m=f.readlines()
    f.close()


def main():
    while(1):
       logHB("Tic")
       if check_listen_wrapper() == False:
          logHB("Server not listening on 16001: Restarting audit")
          RestartAudit()
       else:
          if check_listen_wrapper_banssh() == False:
             logHB("No established connection on 16001: Restarting bansshd")
             RestartBansshd()
             logHB("Restarted Bansshd")
       a=check_bheartbeat()
       if (a == False):
          Restartbheartbeat()
       time.sleep(4)
       b=check_bheartbeat()
       if (a == b):
          Restartbheartbeat()
      
#          else:
#             if check_login_wrapper() == False:
#                   logHB("Restarted Audit and Bansshd")
#                   RestartAudit()
#                   RestartBansshd()
#             time.sleep(12)




if __name__ == "__main__":
     try:
       pid=os.fork()
       if pid > 0:
          sys.exit(0)
     except OSError, e:
       print >> sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
       sys.exit(1)
     os.chdir("/")
     os.setsid()
     os.umask(0)


     try:
       pid = os.fork()
       if pid > 0:
          print "%d" % pid
          f=open('/var/run/bansshJb.py.pid','w')
          f.write(str(pid))
          f.close()
          sys.exit(int(pid))
     except OSError, e:
       print >> sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
       sys.exit(1)
     main()
